#include "common.h"
#include <netinet/in.h>
#include <pthread.h>
#include <ctype.h>
#include "vlan_proce.h"
static MessageBMCInfo _bmcInfo;  //实时上传bmc的信息
extern int udp_cmd_socket;
extern struct sockaddr_in local_src;
volatile int thread_bmc_signal = 0;   //1 运行, 0.结束

int utils_atoi(char s[])
{
    int i;
    int n = 0;
    for (i = 0; s[i] >= '0' && s[i] <= '9'; ++i)
    {
        n = 10 * n + (s[i] - '0');
    }
    return n;
}

float CPU_Sensor_read(char *cmd)
{
    float result_out = 0.0;
    FILE *pipe = popen(cmd, "r"); //打开管道，并执行命令
    if (!pipe)
    {
        return 0; //返回0表示运行失败
    }
    int i = 0;
    char result[64 * 4] = ""; //定义存放结果的字符串数组
    char buffer[64];          //定义缓冲区
    for (i = 0; i < 4; i++)   //读四行
    {
        fgets(buffer, 64, pipe);
        strcat(result, buffer);
    }
    char *cut_addr;
    char cut_result[22];
    cut_addr = strstr(result, "Reading");
    int msb;
    int lsb;
    char observable[25];
    if (NULL != cut_addr)
    {
        strncpy(cut_result, cut_addr, 22);
        msb = utils_atoi(&cut_result[17]);
        lsb = utils_atoi(&cut_result[20]);
        //           printf("msb is %d ,lsb is %d\n",msb,lsb);
        sprintf(observable, "%d.%d", msb, lsb);
        //          printf("%s\n",observable);
        sscanf(observable, "%f", &result_out);
    }
    pclose(pipe); //关闭管道
                    //  printf("result_out is %f\n",result_out);
    return result_out;
}

uint8 internet_status()
{
    float result_out = 0.0;
    FILE *pipe = popen("ifconfig", "r"); //打开管道，并执行命令
    if (!pipe)
    {
        return 0; //返回0表示运行失败
    }
    int i = 0;
    char buff[500]; //定义存放结果的字符串数组
    char *word = "RUNNING,";

    for (i = 0; i < 100; i++)   //读四行
    {
        fgets(buff, 500, pipe);
        if(KT_ERROR != isPresent(buff, 500, word, 8)){
            return 0x01; //返回连接状态
        }
    }

    pclose(pipe); //关闭管道
    return 0x03; //断开状态
}
void read_nvme_temp(char *cmd, uint8 *res) {
    float result_out = 0.0;
    FILE *pipe = popen(cmd, "r"); //打开管道，并执行命令
    if (!pipe)
    {
        return 0; //返回0表示运行失败
    }
    int i = 0;
    char buff[500]; //定义存放结果的字符串数组
    memset(&buff, 0x00, sizeof(buff));
    for (i = 0; i < 1; i++)   //读四行
    {
        fgets(&buff, 500, pipe);
        // LOG_DEBUG("%s] len: %d \n", buff, strlen(buff));
    }
    uint8 *ptr = buff + 9;
    uint8 temp1[4];
    while(*ptr != '\0') {
        uint8 *tp = temp1;
        memset(temp1, 0x0, sizeof(temp1));
        while (isdigit(*ptr) != 0) {
            // LOG_DEBUG("%c ", *ptr);
            *tp++ = *ptr++;
        }
        *res++ = atoi(temp1);
        *ptr++;
        // LOG_DEBUG("\n");
    }
    pclose(pipe); //关闭管道
}
void get_BMC_info(MessageBMCInfo *bmc_info)
{
    float Panel1_P12V = CPU_Sensor_read("ipmitool sdr get 'P12V'");
    float Panel1_CPU_Temp = CPU_Sensor_read("ipmitool sdr get 'CPU Temp'");
    float Panel1_P3V3 = CPU_Sensor_read("ipmitool sdr get 'P3V3'");

    read_nvme_temp("tail -n 1 /home/han/linux_cpu/pserver/check_test.log", &bmc_info->body.cpu1_nvmeTemp);

    char cmd[100];
    sprintf(cmd, "ssh root@%s \"ipmitool sdr get 'P12V'\"", SLAVER_HOST);
    float controlPanel2_12V = CPU_Sensor_read(cmd);

    memset(cmd, 0x0, sizeof(cmd));
    sprintf(cmd, "ssh root@%s \"ipmitool sdr get 'CPU Temp'\"", SLAVER_HOST);
    float controlPanel2_CPUTemp = CPU_Sensor_read(cmd); 

    memset(cmd, 0x0, sizeof(cmd));
    sprintf(cmd, "ssh root@%s \"ipmitool sdr get 'P3V3'\"", SLAVER_HOST);
    float controlPanel2_3_3V = CPU_Sensor_read(cmd); 

    memset(cmd, 0x0, sizeof(cmd)); 
    sprintf(cmd, "ssh root@%s \"tail -n 1 /home/han/linux_cpu/pserver/check_test.log\"", SLAVER_HOST);
    read_nvme_temp(cmd, &bmc_info->body.cpu2_nvmeTemp);

    bmc_info->heade.header = ETH_HEAD;
    bmc_info->heade.type = ETH_TYPE_BMCFF;
    bmc_info->tail.messageLength = sizeof(bmc_info);

    bmc_info->body.networkStatus = 0x01;

    bmc_info->body.controlPanel1_12V = Panel1_P12V;
    bmc_info->body.controlPanel1_CPUTemp = Panel1_CPU_Temp;
    bmc_info->body.controlPanel1_3_3V = Panel1_P3V3; //主板温度改为3.3V电压

    bmc_info->body.controlPanel2_12V = controlPanel2_12V;
    bmc_info->body.controlPanel2_CPUTemp = controlPanel2_CPUTemp;
    bmc_info->body.controlPanel2_3_3V = controlPanel2_3_3V;

    bmc_info->tail.messageLength = sizeof(MessageBMCInfo);
}
// 按照客户需求300ms上报bmc信息
void sendToBMC300ms() {
    while(1) {
        sendto(udp_cmd_socket, &_bmcInfo, sizeof(_bmcInfo), 0, (struct sockaddr *)&local_src, sizeof(local_src));
        usleep(1500*1000);
    }
}

/** 返回发送数据的长度 */
int const_send_data(void *msg, uint8 type)
{
    switch (type)
    {
    case INFO_BMCS:
    {
        LOG_INFO_DEBUG("info type of bmc_info \n");
        MessageBMCInfo *bmc_info = (MessageBMCInfo *)msg;
        get_BMC_info(bmc_info);
        memcpy(&_bmcInfo, bmc_info, sizeof(_bmcInfo));
        return sizeof(MessageBMCInfo);
    }

    case INFO_FILE:
        LOG_INFO_DEBUG("info type of file_info \n");
        return sizeof(FileInfo);
    case INFO_VLAN:
        LOG_INFO_DEBUG("info type of vlan_info \n");
        VlanInfoEth * vinfo = (struct VlanInfoEth *) msg;
        vinfo->head = ETH_HEAD;
        vinfo->type = ETH_TYPE_VLANG;
        vinfo->tail = sizeof(VlanInfoEth);
        VlanStatus * vstatus = &vinfo->vsd;
        VlanStatus * pre_VlanStatus;
        int vinfo_index = 0;
        for (vinfo_index = 0; vinfo_index < VALN_NUM - 1; vinfo_index++) {
            if (vinfo_index < 2) {
                *vstatus++;
                continue;
            }
            if(vinfo_index > 2) {
                pre_VlanStatus = vstatus - 1;
                if (vinfo_index == 2) {
                    pre_VlanStatus->speed += vstatus->speed;
                } else {
                    pre_VlanStatus->speed = vstatus->speed;
                    pre_VlanStatus->status = vstatus->status;
                }
                vstatus->speed = 0;
                vstatus->status = VSTATUS_AWAIT;
                *vstatus++;
            }
        }
        return sizeof(VlanInfoEth);

    case INFO_PCIE:

        break;

    default:
        LOG_ERROR("#ERR: err to send msg, type is: %d \n", type);
        break;
    }
}

void sendToBmcManger(uint8 *data) {
    prctl(PR_SET_NAME, "SEND_BMC_INFO");
    sendToMsg(data, INFO_BMCS);
    free(data);
    pthread_detach(pthread_self()); 
    thread_bmc_signal = 0;
}

/***
 * @param msg 要发送的信息
 * @param type 发送的数据类型
 */
void sendToMsg(void *msg, uint8 type)
{
    int len = const_send_data(msg, type);
    if (len != 0)
    {
        sendto(udp_cmd_socket, msg, len, 0,
               (struct sockaddr *)&local_src,
               sizeof(local_src));
    }
}
